package com.serge.smartdacha;

import java.util.HashMap;
import java.util.Map;

import android.app.Fragment;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.CompoundButton;
import android.widget.SeekBar;
import android.widget.TextView;
import com.serge.smartdacha.model.Controller;
import com.serge.smartdacha.model.CosmController;
import com.serge.smartdacha.model.PerimeterController;
import com.serge.smartdacha.model.SmsParser;
import com.serge.smartdacha.model.TRController;

public class ControlFragment extends Fragment {

    private Map<String, View> trItemView = new HashMap<String, View>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.control_fragment, null);
    }

    @Override
    public void onPause() {
        super.onPause();
        trItemView.clear();
    }

    @Override
    public void onResume() {
        super.onResume();

        stopChronometer();

        ViewGroup trControllersLayout = (ViewGroup) getView().findViewById(R.id.trControllersLayout);
        trControllersLayout.removeAllViews();

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String sms = preferences.getString(MainActivity.PREF_LATEST_SMS_BODY, null);
        if (sms != null) {
            LayoutInflater inflater = getActivity().getLayoutInflater();

            Map<String, Controller> map = new SmsParser().parse(sms);
            for (Controller controller : map.values()) {
                String id = controller.getId();
                if (controller instanceof TRController) {
                    TRController trController = (TRController) controller;

                    View itemView = inflater.inflate(R.layout.trcontrol_item, trControllersLayout, false);


                    SeekBar sbMinTemperature = (SeekBar) itemView.findViewById(R.id.sbMinTemperature);
                    TextView tvMinTemp = (TextView) itemView.findViewById(R.id.tvMinTemp);
                    int progress = trController.toProgress(trController.getMinTemperature(), trController.isRelayOn());
                    sbMinTemperature.setMax(trController.getMaxProgress());
                    sbMinTemperature.setProgress(progress);
                    sbMinTemperature.setSecondaryProgress(trController.toProgress(trController.getTemperature()));

                    OnMinTempChangeListener listener = new OnMinTempChangeListener(trController, tvMinTemp);
                    sbMinTemperature.setOnSeekBarChangeListener(listener);
                    listener.onProgressChanged(sbMinTemperature, sbMinTemperature.getProgress(), false);

                    TextView tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
                    String title = preferences.getString(id + "_title", id);
                    tvTitle.setText(title);

                    trControllersLayout.addView(itemView);
                    trItemView.put(id, itemView);

                } else if (controller instanceof CosmController) {
                    CosmController cosmController = (CosmController) controller;

                    SeekBar sbCosmInterval = (SeekBar) getView().findViewById(R.id.sbCosmInterval);
                    TextView tvCosmInterval = (TextView) getView().findViewById(R.id.tvCosmIntervalControl);

                    sbCosmInterval.setMax(cosmController.getMaxProgress());
                    int progress = cosmController.toProgress(cosmController.getInterval());
                    sbCosmInterval.setProgress(progress);
                    sbCosmInterval.setSecondaryProgress(progress);
                    OnCosmIntervalChangeListener listener = new OnCosmIntervalChangeListener(cosmController, tvCosmInterval);
                    sbCosmInterval.setOnSeekBarChangeListener(listener);
                    listener.onProgressChanged(sbCosmInterval, progress, false);
                } else if (controller instanceof PerimeterController) {
                    PerimeterController perimeterController = (PerimeterController) controller;

                    CheckBox cbPerimeter = (CheckBox) getView().findViewById(R.id.cbPerimeter);
                    cbPerimeter.setChecked(perimeterController.getActive());
                    CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                            compoundButton.setText(b ? "Включен" : "Выключен");
                        }
                    };
                    cbPerimeter.setOnCheckedChangeListener(listener);
                    listener.onCheckedChanged(cbPerimeter, cbPerimeter.isChecked());
                }
            }
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.control, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.miSend:
                sendSms();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void sendSms() {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String sms = preferences.getString(MainActivity.PREF_LATEST_SMS_BODY, null);
        if (sms != null) {
            String smsCommand = "set";
            Map<String, Controller> map = new SmsParser().parse(sms);
            for (Controller controller : map.values()) {
                String id = controller.getId();
                if (controller instanceof TRController) {
                    TRController trController = (TRController) controller;
                    View itemView = trItemView.get(id);
                    SeekBar sbMinTemperature = (SeekBar) itemView.findViewById(R.id.sbMinTemperature);
                    smsCommand += " " + id + "=" + trController.toSmsCommand(sbMinTemperature.getProgress());
                } else if (controller instanceof CosmController) {
                    CosmController cosmController = (CosmController) controller;
                    SeekBar sbCosmInterval = (SeekBar) getView().findViewById(R.id.sbCosmInterval);
                    smsCommand += " " + id + "=" + cosmController.toSmsCommand(sbCosmInterval.getProgress());
                } else if (controller instanceof PerimeterController) {
                    PerimeterController perimeterController = (PerimeterController) controller;
                    CheckBox cbPerimeter = (CheckBox) getView().findViewById(R.id.cbPerimeter);
                    smsCommand += " " + id + "=" + perimeterController.toSmsCommand(cbPerimeter.isChecked());
                }
            }
            ((MainActivity) getActivity()).sendSmsCommand(smsCommand);

            startChronometer();
        }
    }

    private void startChronometer() {
        View controlChronometerLayout = getView().findViewById(R.id.controlChronometerLayout);
        controlChronometerLayout.setVisibility(View.VISIBLE);
        Chronometer chronometer = (Chronometer) getView().findViewById(R.id.controlChronometer);
        chronometer.setBase(SystemClock.elapsedRealtime());
        chronometer.start();
    }

    private void stopChronometer() {
        View controlChronometerLayout = getView().findViewById(R.id.controlChronometerLayout);
        controlChronometerLayout.setVisibility(View.GONE);
        Chronometer chronometer = (Chronometer) getView().findViewById(R.id.controlChronometer);
        chronometer.stop();
    }

    static class OnMinTempChangeListener implements SeekBar.OnSeekBarChangeListener {

        private TRController trController;
        private TextView textView;

        OnMinTempChangeListener(TRController trController, TextView textView) {
            this.trController = trController;
            this.textView = textView;
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            int temp = trController.toMinTemp(progress);
            String text;
            if(temp < 0) {
                text = "Выключено";
            } else if (temp == Integer.MAX_VALUE) {
                text = "Всегда включено";
            } else {
                text = "+" + temp + " C";
            }
            textView.setText(text);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    }

    static class OnCosmIntervalChangeListener implements SeekBar.OnSeekBarChangeListener {

        private CosmController cosmController;

        private TextView textView;

        OnCosmIntervalChangeListener(CosmController cosmController, TextView textView) {
            this.textView = textView;
            this.cosmController = cosmController;
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            int interval = cosmController.toInterval(progress);
            textView.setText(cosmController.toText(textView.getResources(), interval));
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    }
}
